// 在服务器文件顶部添加
process.on('uncaughtException', (err) => {
  console.error('*** 全局未捕获异常 ***:', err);
  console.error(err.stack);
  // 为了调试，暂时不立即退出进程
});

process.on('unhandledRejection', (reason, promise) => {
  console.error('*** 全局未处理的 Promise Rejection ***:', reason);
  console.error(promise);
});

const http = require('http');
const WebSocket = require('ws');
// const { ChatMessage, Doctor, userModel } = require('./database/database');
const { ChatMessage } = require('./database/database');
// const mongoose = require('mongoose');

const server = http.createServer();
const wss = new WebSocket.Server({ server });

const clients = new Map(); // 存储客户端连接：id → WebSocket 实例

// 心跳检测：每30秒清理一次断连的客户端
setInterval(() => {
  clients.forEach((ws, id) => {
    if (ws.readyState !== WebSocket.OPEN) {
      clients.delete(id);
      console.log(`[心跳清理] 移除断连客户端: ${id}`);
    }
  });
}, 30_000); // 30秒 = 30_000毫秒

wss.on('connection', function connection(ws) {
  let id = null;
  console.log('[WebSocket] 新客户端连接，等待ID注册...');

  ws.on('message', async function incoming(message) {
    try {
      const data = JSON.parse(message);
      console.log(`[WebSocket] 收到消息: ${JSON.stringify(data)}`); // 打印收到的所有消息

      // 0. 处理心跳ping消息
      if (data.type === 'ping') {
        // 可以选择回复pong，或直接return
        // ws.send(JSON.stringify({ type: 'pong' }));
        return;
      }

      // 1. 注册身份
      if (!id && (data.userId || data.doctorId)) {
        id = String(data.userId || data.doctorId);
        // 允许任意字符串作为 ID，跳过数据库校验
          clients.set(id, ws);
        console.log(`[WebSocket] User ${id} connected (no DB check).`);
      }
      // 2. 处理 WebRTC 信令消息
      else if (['offer', 'answer', 'ice-candidate', 'call-request', 'call-decline', 'call-ended', 'call-busy', 'webrtc-error'].includes(data.type)) { // 确保包含所有 WebRTC 相关消息类型
        console.log(`[WebRTC 信令] 收到信令消息。当前注册ID: ${id}`);
        if (data.from && data.to) {
          console.log(`[WebRTC 信令] 类型: ${data.type}, from: ${data.from}, to: ${data.to}`);
          const target = clients.get(String(data.to));
          if (target && target.readyState === WebSocket.OPEN) {
            target.send(JSON.stringify(data));
            console.log(`[WebRTC 信令] 成功转发 ${data.type} 给 ${data.to}`);
          } else {
            console.log(`[WebRTC 信令] 目标用户 ${data.to} 不在线或连接未打开，无法转发 ${data.type} 消息。`);
            ws.send(JSON.stringify({
              type: 'webrtc-error',
              originalType: data.type,
              message: `User ${data.to} is offline or not reachable.`,
              to: data.from
            }));
          }
        } else {
          console.warn('[WebRTC 信令] 收到缺少 \'from\' 或 \'to\' 字段的信令消息:', data);
          // 暂时不关闭连接，观察是否是缺失字段导致的问题
        }
      }
      // 3. 处理普通聊天消息 (您原有的逻辑)
      else if (
        data.msgId && data.from && data.to &&
        (data.text || data.imgUrl || data.audioUrl) && // 支持表情、图片、语音
        data.time && data.date
      ) {
        // 新增防御：to字段必须是字符串
        if (typeof data.to !== 'string') {
          console.warn('[聊天消息] to 字段不是字符串，丢弃该消息:', JSON.stringify(data));
          return;
        }
        console.log(`[聊天消息] 收到聊天消息。当前注册ID: ${id}`);
        try {
          await ChatMessage.create(data);
        } catch (e) {
          console.error('[ChatMessage.create] 存储消息失败:', e.message, JSON.stringify(data));
          return;
        }
        ws.send(JSON.stringify({ type: 'ack', msgId: data.msgId }));
        const target = clients.get(String(data.to));
        if (target && target.readyState === WebSocket.OPEN) {
          target.send(JSON.stringify(data));
        } else {
          console.log('[聊天消息] 找不到目标连接:', data.to, '当前所有:', Array.from(clients.keys()));
        }
      }
      // 4. 处理未知消息类型
      else {
        console.warn(`[未知消息类型] 收到消息: ${JSON.stringify(data)}。此消息可能导致连接关闭。`); // 打印未知消息的完整内容
        ws.close(1003, 'Unknown Message Type'); // 如果是未知消息，明确关闭连接并给出原因
      }
    } catch (e) {
      console.error('[异常处理] 消息处理失败:', e.message);
      console.error(e.stack); // 打印堆栈信息
      // 捕获到错误后，这里不立即关闭连接，观察是否是错误导致了隐式关闭
    }
  });

  ws.on('close', function (code, reason) {
    if (id) {
      clients.delete(id); // 断线时从clients删除
      console.log(`[断开] ID: ${id}, 剩余客户端: ${Array.from(clients.keys())}, 关闭代码: ${code}, 原因: ${reason || '无'}`); // 更详细的断开日志
    } else {
      console.log(`[断开] 未注册ID的客户端断开连接，关闭代码: ${code}, 原因: ${reason || '无'}`);
    }
  });

  ws.on('error', (error) => {
    console.error(`[WebSocket 错误] 客户端ID ${id || '未知'}:`, error); // 打印 WebSocket 自身的错误
  });
});
server.listen(4000, () => {
  console.log('WebSocket server running at ws://localhost:4000');
}); 
